package com.aplink.generic.widgets.custom;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.method.KeyListener;
import android.text.method.PasswordTransformationMethod;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.aplink.sg.R;

public class FloatingEditText extends LinearLayout implements TextWatcher,
		View.OnTouchListener, Animator.AnimatorListener, OnFocusChangeListener {
	private Animation bottomUp, bottomDown;
	private TextView mLabel;
	private EditText mValue;

	public FloatingEditText(Context context) {
		super(context);
		init(null, 0);
	}

	public FloatingEditText(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(attrs, 0);
	}

	public FloatingEditText(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(attrs, defStyle);
	}

	private void init(AttributeSet attrs, int defStyle) {
		if (!isInEditMode()) {
			bottomUp = AnimationUtils.loadAnimation(getContext(),
					R.anim.txt_bottom_up);
			bottomDown = AnimationUtils.loadAnimation(getContext(),
					R.anim.txt_bottom_down);
		}
		setOrientation(LinearLayout.VERTICAL);
		mLabel = new TextView(getContext());
		float paddingLeft = TypedValue.applyDimension(
				TypedValue.COMPLEX_UNIT_DIP, 10, getResources()
						.getDisplayMetrics());
		float paddingTop = TypedValue.applyDimension(
				TypedValue.COMPLEX_UNIT_DIP, 5, getResources()
						.getDisplayMetrics());
		mLabel.setPadding((int) paddingLeft, (int) paddingTop, 0, 0);
		mLabel.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
		mLabel.setTextColor(Color.parseColor("#FFAAAAAA"));
		mLabel.setVisibility(View.INVISIBLE);
		mLabel.setAllCaps(true);
		mValue = new EditText(getContext());
		LinearLayout.LayoutParams layoutParams = new LayoutParams(
				LinearLayout.LayoutParams.MATCH_PARENT,
				LayoutParams.WRAP_CONTENT);
		addView(mLabel, layoutParams);
		float marginBottom = TypedValue.applyDimension(
				TypedValue.COMPLEX_UNIT_DIP, 10, getResources()
						.getDisplayMetrics());
		float marginTop = TypedValue.applyDimension(
				TypedValue.COMPLEX_UNIT_DIP, 8, getResources()
						.getDisplayMetrics());
		layoutParams = new LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
				LayoutParams.WRAP_CONTENT);
		layoutParams.setMargins(0, -(int) marginTop, 0, (int) marginBottom);
		addView(mValue, layoutParams);
		setWillNotDraw(false);
		setEvents();
		initTypedArray(attrs);
		mObjectAnimator = ObjectAnimator.ofFloat(this, "touchRadius", 0f, 0f);
		mObjectAnimator2 = ObjectAnimator.ofFloat(this, "touchRadius", 0f, 0f);
		mObjectAnimator.addListener(this);
		paint = new Paint();
		paint.setAntiAlias(true);
		paint.setColor(Color.parseColor("#33B5E5"));
		paint.setAlpha(80);
	}

	private Paint paint = null;
	private String mHint;

	private void initTypedArray(AttributeSet attrs) {
		TypedArray typedArray = getContext().obtainStyledAttributes(attrs,
				R.styleable.FloatingEditText, 0, 0);
		mHint = typedArray.getString(R.styleable.FloatingEditText_hint);
		mValue.setHint(mHint);
		mLabel.setText(mHint);
		setReadOnly(!typedArray.getBoolean(
				R.styleable.FloatingEditText_readOnly, false));
		typedArray.recycle();
	}

	private void setEvents() {
		mValue.addTextChangedListener(this);
		mValue.setOnTouchListener(this);
		mValue.setOnFocusChangeListener(this);
	}

	@Override
	public void beforeTextChanged(CharSequence charSequence, int i, int i2,
			int i3) {

	}

	boolean isLabelShowing;

	@Override
	public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
		if (TextUtils.isEmpty(mValue.getText())) {
			disableHint();
		} else if (mValue.getText().length() >= 1 && !isLabelShowing) {
			showHint();
		}
	}

	private void showHint() {
		mLabel.setText(mHint);
		mLabel.startAnimation(bottomUp);
		mLabel.setVisibility(View.VISIBLE);
		isLabelShowing = true;
	}

	private void disableHint() {
		mLabel.startAnimation(bottomDown);
		mLabel.setVisibility(View.INVISIBLE);
		isLabelShowing = false;
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		canvas.drawCircle(mTouchX,
				getHeight() - (getHeight() - mLabel.getHeight()) / 2,
				touchRadius, paint);
	}

	@Override
	public void afterTextChanged(Editable editable) {

	}

	float mTouchX;
	private float touchRadius;
	private ObjectAnimator mObjectAnimator, mObjectAnimator2;

	@Override
	public boolean onTouch(View view, MotionEvent motionEvent) {
		if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
			mTouchX = motionEvent.getX();
			mObjectAnimator.setFloatValues(touchRadius, getHeight() / 2f);
			mObjectAnimator.setDuration(100);
			mObjectAnimator.start();
		}
		return false;
	}

	public float getTouchRadius() {
		return touchRadius;
	}

	public void setTouchRadius(float touchRadius) {
		this.touchRadius = touchRadius;
		this.invalidate();
	}

	@Override
	public void onAnimationStart(Animator animator) {

	}

	@Override
	public void onAnimationEnd(Animator animator) {
		mObjectAnimator2.setFloatValues(touchRadius, 0);
		mObjectAnimator2.setDuration(100);
		mObjectAnimator2.start();
	}

	@Override
	public void onAnimationCancel(Animator animator) {

	}

	@Override
	public void onAnimationRepeat(Animator animator) {

	}

	public Editable getText() {
		return mValue.getText();
	}

	public void setText(CharSequence editable) {
		mValue.setText(editable);
	}

	public void setText(String editable) {
		mValue.setText(editable);
	}

	public void setHint(String hint) {
		mValue.setHint(hint);
		mHint = hint;
	}

	public CharSequence getHint() {
		return mValue.getHint();
	}

	public void setInputType(int inputType) {
		mValue.setInputType(inputType);
	}

	public void setCursorVisible(boolean visible) {
		mValue.setCursorVisible(visible);
	}

	public void setTransformationMethod(PasswordTransformationMethod method) {
		mValue.setTransformationMethod(method);
	}

	public void setSingleLine(boolean visible) {
		mValue.setSingleLine(visible);
	}

	public void setFilters(InputFilter[] inputFilters) {
		mValue.setFilters(inputFilters);
	}

	public void setKeyListener(KeyListener input) {
		mValue.setKeyListener(input);
	}

	@Override
	public void onFocusChange(View v, boolean hasFocus) {
		if (hasFocus) {
			mLabel.setTextColor(Color.parseColor("#0099CC"));
		} else {
			if (mLabel.getVisibility() == View.VISIBLE) {
				mLabel.setTextColor(Color.parseColor("#FFAAAAAA"));
			}
		}
	}

	public EditText getEditText() {
		return mValue;
	}

	@Override
	public void setEnabled(boolean enabled) {
		mValue.setEnabled(enabled);
		mValue.setFocusable(enabled);
	}

	private boolean isReadOnly;

	public void setReadOnly(boolean isReadOnly) {
		this.isReadOnly = isReadOnly;
		mValue.setCursorVisible(isReadOnly);
		mValue.setFocusable(isReadOnly);
		mValue.setFocusableInTouchMode(isReadOnly);
	}

	public boolean isReadOnly() {
		return isReadOnly;
	}

}
